package com.derbysoft.dswitch.adapter.ihg.dswitch2.service.impl;

import com.derbysoft.dswitch.adapter.ihg.common.log.LogBody;
import com.derbysoft.dswitch.adapter.ihg.common.log.PerformanceLogger;
import com.derbysoft.dswitch.adapter.ihg.common.utils.CollectionUtil;
import com.derbysoft.dswitch.adapter.ihg.common.utils.EnvironmentUtils;
import com.derbysoft.dswitch.adapter.ihg.dswitch2.HotelProviderService;
import com.derbysoft.dswitch.adapter.ihg.dswitch3.translate.Translator;
import com.derbysoft.dswitch.adapter.ihg.dto.OTAHotelAvailRQ;
import com.derbysoft.dswitch.adapter.ihg.dto.OTAHotelAvailRS;
import com.derbysoft.dswitch.adapter.ihg.webservice.handler.WebServiceHandler;
import com.derbysoft.dswitch.adapter.ihg.webservice.impl.AccountProvider;
import com.derbysoft.remote.dswitch.core.GenericRQ;
import com.derbysoft.remote.dswitch.core.GenericRS;
import com.derbysoft.remote.dswitch.core.ResponseHeader;
import com.derbysoft.remote.dswitch.hotel.dto.HotelReservationRQ;
import com.derbysoft.remote.dswitch.hotel.dto.HotelReservationRS;
import com.derbysoft.remote.dswitch.hotel.dto.ReservationRoomStayDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service("ds2hotelPreviewWebService")
public class HotelPreviewWebServiceImpl extends BaseHotelWebService implements
        HotelProviderService<GenericRQ<HotelReservationRQ>, GenericRS<HotelReservationRS>> {

    @Autowired
    @Qualifier("availWebServiceHandler")
    private WebServiceHandler<OTAHotelAvailRQ, OTAHotelAvailRS> hotelAvailWebService;

    @Autowired
    @Qualifier("ds2HotelPreviewRQTranslator")
    private Translator<GenericRQ<HotelReservationRQ>, OTAHotelAvailRQ, Void> hotelPreviewRQTranslator;

    @Autowired
    @Qualifier("ds2HotelPreviewRSTranslator")
    private Translator<OTAHotelAvailRS, GenericRS<HotelReservationRS>, GenericRQ<HotelReservationRQ>> hotelPreviewRSTranslator;

    @Override
    public GenericRS<HotelReservationRS> invoke(GenericRQ<HotelReservationRQ> request) {
        try {
            OTAHotelAvailRQ otaHotelAvailRQ = hotelPreviewRQTranslator.translate(request, null);
            String derbyChannelCode = request.getHeader().getSource().getUniqueID().getId();

            OTAHotelAvailRS otaHotelAvailRS = hotelAvailWebService.invoke(otaHotelAvailRQ, true,
                    AccountProvider.of(EnvironmentUtils.getGlobalIhgAvailabilityUrl(),
                            loadAuthorization(derbyChannelCode)));

            if (otaHotelAvailRS.getErrors() != null && CollectionUtil.isNotEmpty(otaHotelAvailRS.getErrors().getError())) {
                ResponseHeader responseHeader = new ResponseHeader();
                responseHeader.setTaskId(request.getHeader().getTaskId());
                ReservationRoomStayDTO roomStayDTO = request.getPayload().getHotelReservation().getRoomStays().get(0);
                return createNoAllotmentResponse(otaHotelAvailRS, responseHeader, roomStayDTO);
            }
            return hotelPreviewRSTranslator.translate(otaHotelAvailRS, request);
        } catch (Exception ex) {
            GenericRS<HotelReservationRS> failedResponse = createFailedResponse(ex, request);
            PerformanceLogger.append(LogBody.ERROR_CODE, failedResponse.getErrors().getErrorList().get(0).getCode());
            return failedResponse;
        }
    }

    private GenericRS<HotelReservationRS> createFailedResponse(Exception ex, GenericRQ<HotelReservationRQ> request) {
        GenericRS<HotelReservationRS> response = new GenericRS<HotelReservationRS>();
        ResponseHeader header = new ResponseHeader();
        header.setTaskId(request.getHeader().getTaskId());
        response.setHeader(header);
        response.setErrors(createErrorDTO(ex));
        return response;
    }
}